<h1>错误处理</h1>

<p>我们在做 Web 开发的时候，经常需要页面跳转和错误处理，beego 这方面也进行了考虑，通过 <code>Redirect</code> 方法来进行跳转：</p>

<pre lang="go"><code>func (this *AddController) Get() {
    this.Redirect(&quot;/&quot;, 302)
}
</code></pre>

<p>如何中止此次请求并抛出异常，beego 可以在控制器中这样操作：</p>

<pre lang="go"><code>func (this *MainController) Get() {
    this.Abort(&quot;401&quot;)
    v := this.GetSession(&quot;asta&quot;)
    if v == nil {
        this.SetSession(&quot;asta&quot;, int(1))
        this.Data[&quot;Email&quot;] = 0
    } else {
        this.SetSession(&quot;asta&quot;, v.(int)+1)
        this.Data[&quot;Email&quot;] = v.(int)
    }
    this.TplName = &quot;index.tpl&quot;
}
</code></pre>

<p>这样 <code>this.Abort(&quot;401&quot;)</code> 之后的代码不会再执行，而且会默认显示给用户如下页面：</p>

<p><img src="../../images/401.png" alt="" />
</p>

<p>beego 框架默认支持 401、403、404、500、503 这几种错误的处理。用户可以自定义相应的错误处理，例如下面重新定义 404 页面：</p>

<pre lang="go"><code>func page_not_found(rw http.ResponseWriter, r *http.Request){
    t,_:= template.New(&quot;404.html&quot;).ParseFiles(beego.BConfig.WebConfig.ViewsPath+&quot;/404.html&quot;)
    data :=make(map[string]interface{})
    data[&quot;content&quot;] = &quot;page not found&quot;
    t.Execute(rw, data)
}

func main() {
    beego.ErrorHandler(&quot;404&quot;,page_not_found)
    beego.Router(&quot;/&quot;, &amp;controllers.MainController{})
    beego.Run()
}
</code></pre>

<p>我们可以通过自定义错误页面 <code>404.html</code> 来处理 404 错误。</p>

<p>beego 更加人性化的还有一个设计就是支持用户自定义字符串错误类型处理函数，例如下面的代码，用户注册了一个数据库出错的处理页面：</p>

<pre lang="go"><code>func dbError(rw http.ResponseWriter, r *http.Request){
    t,_:= template.New(&quot;dberror.html&quot;).ParseFiles(beego.BConfig.WebConfig.ViewsPath+&quot;/dberror.html&quot;)
    data :=make(map[string]interface{})
    data[&quot;content&quot;] = &quot;database is now down&quot;
    t.Execute(rw, data)
}

func main() {
    beego.ErrorHandler(&quot;dbError&quot;,dbError)
    beego.Router(&quot;/&quot;, &amp;controllers.MainController{})
    beego.Run()
}
</code></pre>

<p>一旦在入口注册该错误处理代码，那么你可以在任何你的逻辑中遇到数据库错误调用 <code>this.Abort(&quot;dbError&quot;)</code> 来进行异常页面处理。</p>

<h1>Controller 定义 Error</h1>

<p>从 1.4.3 版本开始，支持 Controller 方式定义 Error 错误处理函数，这样就可以充分利用系统自带的模板处理，以及 context 等方法。</p>

<pre><code>package controllers

import (
    &quot;github.com/astaxie/beego&quot;
)

type ErrorController struct {
    beego.Controller
}

func (c *ErrorController) Error404() {
    c.Data[&quot;content&quot;] = &quot;page not found&quot;
    c.TplName = &quot;404.tpl&quot;
}

func (c *ErrorController) Error501() {
    c.Data[&quot;content&quot;] = &quot;server error&quot;
    c.TplName = &quot;501.tpl&quot;
}


func (c *ErrorController) ErrorDb() {
    c.Data[&quot;content&quot;] = &quot;database is now down&quot;
    c.TplName = &quot;dberror.tpl&quot;
}
</code></pre>

<p>通过上面的例子我们可以看到，所有的函数都是有一定规律的，都是 <code>Error</code> 开头，后面的名字就是我们调用 <code>Abort</code> 的名字，例如 <code>Error404</code> 函数其实调用对应的就是 <code>Abort(&quot;404&quot;)</code></p>

<p>我们就只要在 <code>beego.Run</code> 之前采用 <code>beego.ErrorController</code> 注册这个错误处理函数就可以了</p>

<pre><code>package main

import (
    _ &quot;btest/routers&quot;
    &quot;btest/controllers&quot;

    &quot;github.com/astaxie/beego&quot;
)

func main() {
    beego.ErrorController(&amp;controllers.ErrorController{})
    beego.Run()
}

</code></pre>